home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / bbs / fmail122.zip / FMSTRUCT.ZIP / CFGFILE.C next >
C/C++ Source or Header  |  1996-09-26  |  11KB  |  320 lines

  1. /*
  2.    CFGFILE.C
  3.  
  4.    Config file interface routines for FMail 1.21
  5.    Copyright (C) 1996 Folkert J. Wijnstra. All rights reserved.
  6.  
  7.    All information in this document is subject to change at any time
  8.    without prior notice!
  9. */
  10.  
  11.  
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <fcntl.h>
  15. #include <sys\stat.h>
  16. #include <io.h>
  17. #include <time.h>
  18.  
  19. #include "fmstruct.h"
  20. #include "cfgfile.h"
  21. #include "internal.h" /* not necessary for 3rd party programs */
  22.  
  23.  
  24. /* set to non-zero value if automatic conversion is desired */
  25. u16  allowConversion = 0;
  26.  
  27.  
  28. typedef struct
  29. {
  30.    const char     *fileName;
  31.    const u16      recordSize;
  32.    fhandle        handle;
  33.    char           *recBuf;
  34.    char           *revString;
  35.    u16            revNumber;
  36.    const u16      dataType;
  37.    const u16      init;
  38.    u16            status;
  39.    headerType     header;
  40. } configFileInfoType;
  41.  
  42.  
  43. static configFileInfoType fileData[MAX_CFG_FILES] =
  44.    {
  45.     /* CFG_GENERAL */
  46.     {       "FMAIL.CFG", sizeof(configType),    -1, NULL,
  47.                 "FMail Configuration File rev. 1.1\x1a",
  48.                  0x0110, DATATYPE_CF, 'CF', 0 },
  49.     /* CFG_NODES */
  50.     {       "FMAIL.NOD", sizeof(nodeInfoType), -1, NULL,
  51.                 "FMail Node File rev. 1.1\x1a",
  52.                  0x0110, DATATYPE_NO, 'NO', 0 },
  53.     /* CFG_ECHOAREAS */
  54.     {       "FMAIL.AR",  sizeof(rawEchoType),  -1, NULL,
  55.                 "FMail Area File rev. 1.1\x1a",
  56.                  0x0110, DATATYPE_AE, 'AE', 0 },
  57.     /* CFG_AREADEF */
  58.     {       "FMAIL.ARD", sizeof(rawEchoType),  -1, NULL,
  59.                 "FMail Area File rev. 1.1\x1a",
  60.                  0x0110, DATATYPE_AD, 'AD', 0 } };
  61.  
  62.  
  63. static configFileInfoType cfiArr[MAX_CFG_FILES];
  64.  
  65. extern char configPath[128]; /* Path to directory with FMail config files */
  66.  
  67.  
  68.  
  69. s16 openConfig(u16 fileType, headerType **header, void **buf)
  70. {
  71.    pathType areaInfoPath, tempPath;
  72.    fhandle  temphandle;
  73.    uchar    *helpPtr;
  74.    u16        count;
  75.    u16      orgRecSize;
  76.    u16      converted = 0;
  77.  
  78.    if (fileType >= MAX_CFG_FILES) return 0;
  79.  
  80. restart:
  81.    strcpy(areaInfoPath, configPath);
  82.    strcat(areaInfoPath, fileData[fileType].fileName);
  83.  
  84.    memset(&cfiArr[fileType].header, 0, sizeof(headerType));
  85.    cfiArr[fileType].status = 0;
  86.  
  87.    if ((cfiArr[fileType].handle = open(areaInfoPath, O_BINARY|O_RDWR|O_CREAT|O_DENYALL, S_IREAD|S_IWRITE)) == -1)
  88.    {  return 0;
  89.    }
  90.    if (filelength(cfiArr[fileType].handle) == 0)
  91.    {
  92.       strcpy(cfiArr[fileType].header.versionString, fileData[fileType].revString);
  93.       cfiArr[fileType].header.revNumber    = fileData[fileType].revNumber;
  94.       cfiArr[fileType].header.headerSize   = sizeof(headerType);
  95.       cfiArr[fileType].header.recordSize   = fileData[fileType].recordSize;
  96.       cfiArr[fileType].header.dataType     = fileData[fileType].dataType;
  97.       cfiArr[fileType].header.totalRecords = 0;
  98.       cfiArr[fileType].header.lastModified = time(&cfiArr[fileType].header.creationDate);
  99.  
  100.       write(cfiArr[fileType].handle, &cfiArr[fileType].header, sizeof(headerType));
  101.    }
  102.    else
  103.    {
  104.       read(cfiArr[fileType].handle, &cfiArr[fileType].header, sizeof(headerType));
  105.  
  106.       if (memcmp(cfiArr[fileType].header.versionString, "FMail", 5) ||
  107.           (cfiArr[fileType].header.headerSize < sizeof(headerType)) ||
  108.           ((!allowConversion || converted) && cfiArr[fileType].header.recordSize < fileData[fileType].recordSize) ||
  109.       (cfiArr[fileType].header.dataType != fileData[fileType].dataType))
  110.       {
  111. error:   close(cfiArr[fileType].handle);
  112.      cfiArr[fileType].handle = -1;
  113.      *header = NULL;
  114.      *buf = NULL;
  115.      return 0;
  116.       }
  117.       if (cfiArr[fileType].header.recordSize < fileData[fileType].recordSize)
  118.       {
  119.          /* convert old record format */
  120.          strcpy(tempPath, areaInfoPath);
  121.          if ( (helpPtr = strrchr(tempPath, '.')) == NULL )
  122.             goto error;
  123.          strcpy(helpPtr+1, "$$$");
  124.          if ((cfiArr[fileType].recBuf = malloc(fileData[fileType].recordSize)) == NULL)
  125.             goto error;
  126.          if ((temphandle = open(tempPath, O_BINARY|O_RDWR|O_CREAT|O_DENYALL, S_IREAD|S_IWRITE)) == -1)
  127.          {  free(cfiArr[fileType].recBuf);
  128.             cfiArr[fileType].recBuf = NULL;
  129.             goto error;
  130.          }
  131.          orgRecSize = cfiArr[fileType].header.recordSize;
  132.          strcpy(cfiArr[fileType].header.versionString, fileData[fileType].revString);
  133.          cfiArr[fileType].header.revNumber    = fileData[fileType].revNumber;
  134.          cfiArr[fileType].header.headerSize   = sizeof(headerType);
  135.          cfiArr[fileType].header.recordSize   = fileData[fileType].recordSize;
  136.          cfiArr[fileType].header.dataType     = fileData[fileType].dataType;
  137.          time(&cfiArr[fileType].header.lastModified);
  138.          write(temphandle, &cfiArr[fileType].header, sizeof(headerType));
  139.          for ( count = 0; count < cfiArr[fileType].header.totalRecords; count++ )
  140.          {  memset(cfiArr[fileType].recBuf, 0, fileData[fileType].recordSize);
  141.             if ( read(cfiArr[fileType].handle, cfiArr[fileType].recBuf, orgRecSize) != orgRecSize )
  142.             {  free(cfiArr[fileType].recBuf);
  143.                cfiArr[fileType].recBuf = NULL;
  144.                close(temphandle);
  145.                unlink(tempPath);
  146.                goto error;
  147.             }
  148.             if (write(temphandle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) !=
  149.                                                            cfiArr[fileType].header.recordSize)
  150.             {  free(cfiArr[fileType].recBuf);
  151.                cfiArr[fileType].recBuf = NULL;
  152.                close(temphandle);
  153.                unlink(tempPath);
  154.                goto error;
  155.             }
  156.          }
  157.          converted = 1;
  158.          free(cfiArr[fileType].recBuf);
  159.          cfiArr[fileType].recBuf = NULL;
  160.          close(temphandle);
  161.          close(cfiArr[fileType].handle);
  162.          unlink(areaInfoPath);
  163.          rename(tempPath, areaInfoPath);
  164.      cfiArr[fileType].handle = -1;
  165.      *header = NULL;
  166.          *buf = NULL;
  167.          goto restart;
  168.       }
  169.    }
  170.    if ((cfiArr[fileType].recBuf = malloc(cfiArr[fileType].header.recordSize)) == NULL)
  171.       goto error;
  172.    *header = &cfiArr[fileType].header;
  173.    *buf    = cfiArr[fileType].recBuf;
  174.    return 1;
  175. }
  176.  
  177.  
  178. s16 getRec(u16 fileType, s16 index)
  179. {
  180.    if (cfiArr[fileType].handle == -1) return 0;
  181.  
  182.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  183.              cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  184.    {  return 0;
  185.    }
  186.    if (read(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  187.    {  return 0;
  188.    }
  189.    return 1;
  190. }
  191.  
  192.  
  193. s16 putRec(u16 fileType, s16 index)
  194. {
  195.    if (cfiArr[fileType].handle == -1) return 0;
  196.  
  197.    *(u16*)cfiArr[fileType].recBuf = fileData[fileType].init;
  198.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  199.              cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  200.    {  return 0;
  201.    }
  202.    if (write (cfiArr[fileType].handle, cfiArr[fileType].recBuf,
  203.           cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  204.    {  return 0;
  205.    }
  206.    cfiArr[fileType].status = 1;
  207.    return 1;
  208. }
  209.  
  210.  
  211. s16 insRec(u16 fileType, s16 index)
  212. {
  213.    s16  count;
  214.    void *tempBuf;
  215.  
  216.    if (cfiArr[fileType].handle == -1) return 0;
  217.  
  218.    *(u16*)cfiArr[fileType].recBuf = fileData[fileType].init;
  219.  
  220.    if ((tempBuf = malloc(cfiArr[fileType].header.recordSize)) == NULL) return 0;
  221.    count = cfiArr[fileType].header.totalRecords;
  222.  
  223.    while (--count >= index)
  224.    {  if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  225.                 cfiArr[fileType].header.recordSize*(s32)count, SEEK_SET) == -1)
  226.       {  free(tempBuf);
  227.      return 0;
  228.       }
  229.       if (read(cfiArr[fileType].handle, tempBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  230.       {  free(tempBuf);
  231.      return 0;
  232.       }
  233.       if (write(cfiArr[fileType].handle, tempBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  234.       {  free(tempBuf);
  235.      return 0;
  236.       }
  237.    }
  238.    free(tempBuf);
  239.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  240.              cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  241.    {  return 0;
  242.    }
  243.    if (write(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  244.    {  return 0;
  245.    }
  246.    cfiArr[fileType].header.totalRecords++;
  247.    if (lseek(cfiArr[fileType].handle, 0, SEEK_SET) == -1)
  248.    {  return 0;
  249.    }
  250.    time(&cfiArr[fileType].header.lastModified);
  251.    if (write(cfiArr[fileType].handle, &cfiArr[fileType].header, cfiArr[fileType].header.headerSize) != cfiArr[fileType].header.headerSize)
  252.    {  return 0;
  253.    }
  254.    cfiArr[fileType].status = 1;
  255.    return 1;
  256. }
  257.  
  258.  
  259. s16 delRec(u16 fileType, s16 index)
  260. {
  261.    if (cfiArr[fileType].handle == -1) return 0;
  262.    while (++index < cfiArr[fileType].header.totalRecords)
  263.    {  if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  264.                 cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  265.       {  return 0;
  266.       }
  267.       if (read(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  268.       {  return 0;
  269.       }
  270.       if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  271.                 cfiArr[fileType].header.recordSize*(s32)(index-1), SEEK_SET) == -1)
  272.       {  return 0;
  273.       }
  274.       if (write(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  275.       {  return 0;
  276.       }
  277.    }
  278.    chsize(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  279.           cfiArr[fileType].header.recordSize*(s32)--cfiArr[fileType].header.totalRecords);
  280.  
  281.    if (lseek(cfiArr[fileType].handle, 0, SEEK_SET) == -1)
  282.    {  return 0;
  283.    }
  284.    time(&cfiArr[fileType].header.lastModified);
  285.    write(cfiArr[fileType].handle, &cfiArr[fileType].header, cfiArr[fileType].header.headerSize);
  286.  
  287.    cfiArr[fileType].status = 1;
  288.    return 1;
  289. }
  290.  
  291.  
  292. s16 chgNumRec(u16 fileType, s16 number)
  293. {
  294.     cfiArr[fileType].header.totalRecords = number;
  295.     cfiArr[fileType].status = 1;
  296.     return 1;
  297. }
  298.  
  299.  
  300. s16 closeConfig(u16 fileType)
  301. {
  302.    if (cfiArr[fileType].handle == -1) return 0;
  303.  
  304.    if ((cfiArr[fileType].status == 1) &&
  305.        (lseek(cfiArr[fileType].handle, 0, SEEK_SET) != -1))
  306.    {
  307.       time(&cfiArr[fileType].header.lastModified);
  308.       write(cfiArr[fileType].handle, &cfiArr[fileType].header, cfiArr[fileType].header.headerSize);
  309.       chsize(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  310.                       cfiArr[fileType].header.recordSize*
  311.                                       (s32)cfiArr[fileType].header.totalRecords);
  312.    }
  313.    close(cfiArr[fileType].handle);
  314.    cfiArr[fileType].handle = -1;
  315.    free(cfiArr[fileType].recBuf);
  316.    cfiArr[fileType].recBuf = NULL;
  317.  
  318.    return 1;
  319. }
  320.